/* $Id:item.h $ */
/*
   Copyright (C) 2007 by Jurjen Stellingwerff <jurjen@stwerff.xs4all.nl>
   Part of the Moros Project http://moros.sourceforge.net/

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 3.
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY.

   See the COPYING file for more details.
*/

#ifndef __ITEM_H
#define __ITEM_H

#include <string>
#include <map>
#include <list>
using namespace std;

#include "action_level.h"
#include "action_skill.h"
#include "material.h"
#include "action_bonus.h"
#include "item_spell.h"

#define loopItemUsage(r,v) loopMapi((r)->listUsage(),v,class action_level)
#define loopItemCreation(r,v) loopMap((r)->listCreation(),v,class action_skill)
#define loopItemMaterial(r,v) loopSingle((r)->listMaterial(),v,class material,list)
#define loopItemBonus(r,v) loopMapi((r)->listBonus(),v,class action_bonus)
#define loopItemSpell(r,v) loopMap((r)->listSpell(),v,class item_spell)

class item {
    string name;
    int nr;
    string description;
    int status;
    int type;
    int weight;
    class skill *skill;
    class special *special;
    map<int,class action_level> usage;
    int maxUsage;
    map<string,class action_skill> creation;
    map<string,class material> material;
    map<int,class action_bonus> bonus;
    int maxBonus;
    map<string,class item_spell> spell;
public:
    item();

    // Field : name
    const string getName() const;
    void setName(const string v);

    // Field : nr
    const int getNr() const;
    void setNr(const int v);
    int operator<(const class item &ck) const;

    // Field : description
    const string getDescription() const;
    void setDescription(const string v);

    // Field : status
    const int getStatus() const;
    void setStatus(const int v);

    // Field : type
    enum type_enum{type_tool,type_cutting_weapon,type_blunt_weapon,type_impaling_weapon,type_transport,type_building,type_good};
    const int getType() const;
    const string showType() const;
    void setType(const int v);
    void setType(const string v);

    // Field : weight
    const int getWeight() const;
    void setWeight(const int v);

    // Field : skill
    class skill& getSkill() const;
    void setSkill(class skill &v);

    // Field : special
    class special& getSpecial() const;
    void setSpecial(class special &v);

    // Field : usage
    class action_level& getUsage(const int v);
    map<int,class action_level>& listUsage();
    void setUsage(class action_level &v);
    void delUsage(const int v);
    const bool isUsage(const int v) const;

    // Field : creation
    class action_skill& getCreation(const string v);
    map<string,class action_skill>& listCreation();
    void setCreation(class action_skill &v);
    void delCreation(const string v);
    const bool isCreation(const string v) const;

    // Field : material
    class material& getMaterial(const string v);
    list<class material>& listMaterial();
    void setMaterial(class material &v);
    void delMaterial(const string v);
    const bool isMaterial(const string v) const;

    // Field : bonus
    class action_bonus& getBonus(const int v);
    map<int,class action_bonus>& listBonus();
    void setBonus(class action_bonus &v);
    void delBonus(const int v);
    const bool isBonus(const int v) const;

    // Field : spell
    class item_spell& getSpell(const string v);
    map<string,class item_spell>& listSpell();
    void setSpell(class item_spell &v);
    void delSpell(const string v);
    const bool isSpell(const string v) const;

    void save(class channel &ch);
    void load(class channel &ch);
    void xml(ofstream &f, int l=0, int r=0);
};

// Repository

#define loopItems(v) loopSingle(item_repo.listItem(),v,class item,list)

class itemRepository {
    map<string,item> items;
    int max_nr;
public:
    itemRepository();
    class item& getItem(const string v);
    void setItem(class item& v);
    list<class item>& listItem();
    void delItem(const string v);
    const bool isItem(const string v) const;
    multimap<string, sigc::signal<void, class item& > > relations;
    bool load(class channel &ch);
    void save(class channel &ch);
};

extern itemRepository item_repo;

#endif // __ITEM_H
